import { Singleton, Inject } from 'typescript-ioc'
import { IBootStrap } from 'bootstrap'
import axios from 'axios'
import uuid from 'node-uuid'
import { LoggerService } from './logger.service'
import { ConfigService } from './config.service'
import { DISCOVERY_CLUSTER, SERVICE_NAME, SERVICE_INGRESS, SERVICE_CLUSTER } from '../common/constants'

@Singleton
export class ConsulService implements IBootStrap {
  private consulAddress
  private serviceIngress
  private serviceName
  private serviceCluster

  @Inject
  private config: ConfigService
  @Inject
  private logger: LoggerService

  constructor() {
    const consulHost = this.config.get(DISCOVERY_CLUSTER)
    this.serviceName = this.config.get(SERVICE_NAME)
    this.serviceIngress = this.config.get(SERVICE_INGRESS)
    this.serviceCluster = this.config.get(SERVICE_CLUSTER)
    this.consulAddress = `http://${consulHost}/discovery/services`
  }

  /**
   * 检测是否已经注册
   */
  private checkRegister() {
    return axios({
      url: `${this.consulAddress}/${this.serviceName}`,
      method: 'GET'
    })
  }

  /**
   * 开始注册
   */
  startRegiser() {
    const serviceId = uuid.v1()

    return axios({
      url: this.consulAddress,
      method: 'POST',
      data: {
        ID: serviceId,
        Name: this.serviceName,
        Address: this.serviceIngress,
        Port: 443,
        Tags: [this.serviceName],
        Check: {
          ID: `${this.serviceName}-check-${serviceId}`,
          Name: `${this.serviceName}-check`,
          HTTP: `http://${this.serviceCluster}:8080`,
          Interval: '30s',
          Timeout: '5s',
          DeregisterCriticalServiceAfter: '3m',
          TLSSkipVerify: false
        },
        Meta: {
          LocalHost: this.serviceCluster,
          Schema: 'http',
          LocalPort: '8080'
        }
      }
    }).then(() => {
      this.logger.log('Consul服务注册成功')
    })
  }

  /**
   * 注册Consul服务
   */
  public register() {
    return this.checkRegister()
      .then(async ({ data }) => {
        if (data.length === 0) {
          await this.startRegiser()
        } else {
          this.logger.log('Consul查询注册成功', data)
        }
      })
      .catch(err => {
        this.logger.log('CONSUL服务注册失败', err.message)
      })
  }
}
